Skip to main content

Q-2 Alternative: Canvas & Paints OR Fade In & Zoom Out Animation (5 Marks)

Questions​

a) Write a note on working of canvas and paints in android application. (5 marks)

OR

b) Write a code to demonstrate the use of 'Fade In' and 'Zoom Out' animation in android application. (5 marks)


Answers​

a) Canvas and Paints in Android Application​

Canvas Overview​

Canvas is a 2D drawing surface in Android that provides methods for drawing graphics, text, and images. It acts as a drawing board where you can draw shapes, paths, text, and bitmaps.

Paint Overview​

Paint is a class that holds styling and color information about how to draw geometries, text, and bitmaps on the Canvas.

Key Concepts​

1. Canvas Functionality

  • Drawing Surface: Provides 2D drawing capabilities
  • Coordinate System: Uses (0,0) at top-left corner
  • Drawing Methods: Lines, rectangles, circles, paths, text, bitmaps
  • Transformations: Rotate, scale, translate, skew
  • Clipping: Restrict drawing to specific regions

2. Paint Properties

  • Color: Set drawing color
  • Style: Fill, stroke, or both
  • Stroke Width: Line thickness
  • Anti-aliasing: Smooth edges
  • Text Properties: Size, typeface, alignment

Canvas Drawing Methods​

// Basic shapes
canvas.drawRect(left, top, right, bottom, paint);
canvas.drawCircle(cx, cy, radius, paint);
canvas.drawLine(startX, startY, stopX, stopY, paint);
canvas.drawOval(oval, paint);

// Text
canvas.drawText(text, x, y, paint);

// Bitmaps
canvas.drawBitmap(bitmap, x, y, paint);

// Paths
Path path = new Path();
path.moveTo(x1, y1);
path.lineTo(x2, y2);
canvas.drawPath(path, paint);

Complete Example: Custom Drawing View​

public class CustomDrawingView extends View {
private Paint paintCircle, paintRect, paintText, paintLine;
private Path customPath;

public CustomDrawingView(Context context) {
super(context);
initPaints();
}

public CustomDrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
initPaints();
}

private void initPaints() {
// Paint for filled circle
paintCircle = new Paint();
paintCircle.setColor(Color.BLUE);
paintCircle.setStyle(Paint.Style.FILL);
paintCircle.setAntiAlias(true);

// Paint for rectangle outline
paintRect = new Paint();
paintRect.setColor(Color.RED);
paintRect.setStyle(Paint.Style.STROKE);
paintRect.setStrokeWidth(5f);
paintRect.setAntiAlias(true);

// Paint for text
paintText = new Paint();
paintText.setColor(Color.BLACK);
paintText.setTextSize(48f);
paintText.setTypeface(Typeface.DEFAULT_BOLD);
paintText.setAntiAlias(true);

// Paint for lines
paintLine = new Paint();
paintLine.setColor(Color.GREEN);
paintLine.setStrokeWidth(3f);
paintLine.setAntiAlias(true);

// Create custom path
customPath = new Path();
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

// Get canvas dimensions
int width = getWidth();
int height = getHeight();

// Draw background
canvas.drawColor(Color.LTGRAY);

// Draw filled circle
canvas.drawCircle(width * 0.2f, height * 0.2f, 50f, paintCircle);

// Draw rectangle outline
canvas.drawRect(width * 0.1f, height * 0.4f,
width * 0.4f, height * 0.6f, paintRect);

// Draw text
canvas.drawText("Custom View", width * 0.1f, height * 0.8f, paintText);

// Draw lines
canvas.drawLine(0, height * 0.5f, width, height * 0.5f, paintLine);
canvas.drawLine(width * 0.5f, 0, width * 0.5f, height, paintLine);

// Draw custom path (triangle)
customPath.reset();
customPath.moveTo(width * 0.7f, height * 0.2f);
customPath.lineTo(width * 0.9f, height * 0.4f);
customPath.lineTo(width * 0.5f, height * 0.4f);
customPath.close();

Paint pathPaint = new Paint();
pathPaint.setColor(Color.MAGENTA);
pathPaint.setStyle(Paint.Style.FILL);
canvas.drawPath(customPath, pathPaint);

// Draw arc
RectF arcRect = new RectF(width * 0.6f, height * 0.6f,
width * 0.9f, height * 0.9f);
canvas.drawArc(arcRect, 0, 180, true, paintCircle);
}

// Method to change colors dynamically
public void setCircleColor(int color) {
paintCircle.setColor(color);
invalidate(); // Trigger redraw
}
}

Using Custom View in Activity​

public class MainActivity extends AppCompatActivity {
private CustomDrawingView customView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// Create and set custom view
customView = new CustomDrawingView(this);
setContentView(customView);

// Optional: Add to existing layout
// LinearLayout layout = findViewById(R.id.container);
// layout.addView(customView);
}
}

Advanced Paint Techniques​

// Gradient effects
LinearGradient gradient = new LinearGradient(0, 0, 100, 100,
Color.RED, Color.BLUE, Shader.TileMode.MIRROR);
paint.setShader(gradient);

// Shadow effects
paint.setShadowLayer(10f, 5f, 5f, Color.GRAY);

// Dash effects
DashPathEffect dashEffect = new DashPathEffect(new float[]{10, 5}, 0);
paint.setPathEffect(dashEffect);

// Blur effects
BlurMaskFilter blur = new BlurMaskFilter(15, BlurMaskFilter.Blur.NORMAL);
paint.setMaskFilter(blur);

b) Fade In and Zoom Out Animation Implementation​

Step 1: Create Animation XML Files​

res/anim/fade_in_animation.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="1500"
android:fillAfter="true" />
</set>

res/anim/zoom_out_animation.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale="0.1"
android:toYScale="0.1"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000"
android:fillAfter="true" />
</set>

res/anim/combined_fade_zoom.xml (Optional combined animation):

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="1500" />
<scale
android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale="0.0"
android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="1500" />
</set>

Step 2: Layout XML​

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">

<ImageView
android:id="@+id/fadeInImage"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:src="@drawable/ic_star"
android:alpha="0.0" />

<TextView
android:id="@+id/zoomOutText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/fadeInImage"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:text="Zoom Out Text"
android:textSize="24sp"
android:textStyle="bold"
android:textColor="@android:color/holo_blue_dark" />

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/zoomOutText"
android:layout_centerHorizontal="true"
android:layout_marginTop="80dp"
android:orientation="vertical">

<Button
android:id="@+id/btnFadeIn"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="Start Fade In"
android:layout_marginBottom="16dp" />

<Button
android:id="@+id/btnZoomOut"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="Start Zoom Out"
android:layout_marginBottom="16dp" />

<Button
android:id="@+id/btnReset"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="Reset Views"
android:layout_marginBottom="16dp" />

<Button
android:id="@+id/btnCombined"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="Combined Animation" />
</LinearLayout>
</RelativeLayout>

Step 3: MainActivity Java Code​

public class MainActivity extends AppCompatActivity {
private ImageView fadeInImage;
private TextView zoomOutText;
private Button btnFadeIn, btnZoomOut, btnReset, btnCombined;

private Animation fadeInAnimation, zoomOutAnimation, combinedAnimation;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

initViews();
loadAnimations();
setupClickListeners();
}

private void initViews() {
fadeInImage = findViewById(R.id.fadeInImage);
zoomOutText = findViewById(R.id.zoomOutText);
btnFadeIn = findViewById(R.id.btnFadeIn);
btnZoomOut = findViewById(R.id.btnZoomOut);
btnReset = findViewById(R.id.btnReset);
btnCombined = findViewById(R.id.btnCombined);
}

private void loadAnimations() {
fadeInAnimation = AnimationUtils.loadAnimation(this, R.anim.fade_in_animation);
zoomOutAnimation = AnimationUtils.loadAnimation(this, R.anim.zoom_out_animation);
combinedAnimation = AnimationUtils.loadAnimation(this, R.anim.combined_fade_zoom);

// Set animation listeners
fadeInAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Toast.makeText(MainActivity.this, "Fade In Started", Toast.LENGTH_SHORT).show();
}

@Override
public void onAnimationEnd(Animation animation) {
Toast.makeText(MainActivity.this, "Fade In Completed", Toast.LENGTH_SHORT).show();
}

@Override
public void onAnimationRepeat(Animation animation) {}
});

zoomOutAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Toast.makeText(MainActivity.this, "Zoom Out Started", Toast.LENGTH_SHORT).show();
}

@Override
public void onAnimationEnd(Animation animation) {
Toast.makeText(MainActivity.this, "Zoom Out Completed", Toast.LENGTH_SHORT).show();
}

@Override
public void onAnimationRepeat(Animation animation) {}
});
}

private void setupClickListeners() {
btnFadeIn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startFadeInAnimation();
}
});

btnZoomOut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startZoomOutAnimation();
}
});

btnReset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
resetViews();
}
});

btnCombined.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startCombinedAnimation();
}
});
}

private void startFadeInAnimation() {
fadeInImage.setAlpha(0.0f); // Start invisible
fadeInImage.startAnimation(fadeInAnimation);
}

private void startZoomOutAnimation() {
zoomOutText.setScaleX(1.0f); // Reset scale
zoomOutText.setScaleY(1.0f);
zoomOutText.startAnimation(zoomOutAnimation);
}

private void resetViews() {
// Clear animations
fadeInImage.clearAnimation();
zoomOutText.clearAnimation();

// Reset properties
fadeInImage.setAlpha(0.0f);
zoomOutText.setScaleX(1.0f);
zoomOutText.setScaleY(1.0f);

Toast.makeText(this, "Views Reset", Toast.LENGTH_SHORT).show();
}

private void startCombinedAnimation() {
zoomOutText.startAnimation(combinedAnimation);
}
}

Alternative: Programmatic Animation Creation​

// Create fade in animation programmatically
private Animation createFadeInAnimation() {
AlphaAnimation fadeIn = new AlphaAnimation(0.0f, 1.0f);
fadeIn.setDuration(1500);
fadeIn.setFillAfter(true);
return fadeIn;
}

// Create zoom out animation programmatically
private Animation createZoomOutAnimation() {
ScaleAnimation zoomOut = new ScaleAnimation(
1.0f, 0.1f, // X scale from 1.0 to 0.1
1.0f, 0.1f, // Y scale from 1.0 to 0.1
Animation.RELATIVE_TO_SELF, 0.5f, // Pivot X
Animation.RELATIVE_TO_SELF, 0.5f // Pivot Y
);
zoomOut.setDuration(2000);
zoomOut.setFillAfter(true);
return zoomOut;
}

// Create combined animation
private AnimationSet createCombinedAnimation() {
AnimationSet animationSet = new AnimationSet(true);

AlphaAnimation fadeOut = new AlphaAnimation(1.0f, 0.0f);
fadeOut.setDuration(1500);

ScaleAnimation zoomOut = new ScaleAnimation(
1.0f, 0.0f, 1.0f, 0.0f,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f
);
zoomOut.setDuration(1500);

animationSet.addAnimation(fadeOut);
animationSet.addAnimation(zoomOut);
animationSet.setFillAfter(true);

return animationSet;
}

Key Animation Properties​

  • Duration: Time for animation to complete
  • FillAfter: Keep final state after animation
  • FillBefore: Keep initial state before animation
  • RepeatCount: Number of repetitions
  • RepeatMode: Restart or reverse
  • Interpolator: Animation timing curve